/*
 *    Copyright (c) 2014 Xiang Xu <xuxiang@mail.bnu.edu.cn>
 *
 *    Permission is hereby granted, free of charge, to any person
 *    obtaining a copy of this software and associated documentation
 *    files (the "Software"), to deal in the Software without
 *    restriction, including without limitation the rights to use,
 *    copy, modify, merge, publish, distribute, sublicense, and/or sell
 *    copies of the Software, and to permit persons to whom the
 *    Software is furnished to do so, subject to the following
 *    conditions:
 *
 *    The above copyright notice and this permission notice shall be
 *    included in all copies or substantial portions of the Software.
 *
 *    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 *    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 *    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 *    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 *    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 *    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *    OTHER DEALINGS IN THE SOFTWARE.
 */

#ifndef SHAPE_SYMBOL_H
#define SHAPE_SYMBOL_H

#include "shape_grammar.h"
#include "boost/smart_ptr.hpp"

class FacadeGrammar;

//! Shape symbol definition of the Shape Grammar.
/*! A shape symbol has its rectangle envelope and its type. */
class ShapeSymbol
{
public:
    //! Constructors
    /*!
     \ param facade_grammar T*he facade grammar that this shape symbol is in.
     */
    ShapeSymbol(boost::shared_ptr<FacadeGrammar> facade_grammar);
    //! Constructors
    /*!
     \ param x x position of *the left bottom corner of this shape symbol.
     \param y y position of the left bottom corner of this shape symbol.
     \param w width of this shape symbol.
     \param h height of this shape symbol.
     \param name the name of this shape symbol.
     \param facade_grammar the facade grammar that this shape symbol is in.
     */
    ShapeSymbol(int x, int y, int w, int h, std::string name, boost::shared_ptr<FacadeGrammar> facade_grammar);
    ~ShapeSymbol() {}

    //! Set the envelop
    /*!
     \ param x x position of *the left bottom corner of this shape symbol.
     \param y y position of the left bottom corner of this shape symbol.
     \param w width of this shape symbol.
     \param h height of this shape symbol.
     \return void.
     */
    void SetScope(int x, int y, int w, int h);

    //! Split this shape symbol to two sub symbols with a given split action.
    /*!
     \ param split_action The* action that used to split this symbol.
     \param right_symbol_1 The first sub symbol.
     \param right_symbol_2 The second sub symbol.
     \param width the facade width.
     \param height the facade height.
     \return true if the split success, otherwise false. If is false, the right_symbol_1 is the exception symbol.
     */
    bool DoSplit(ShapeGrammar& shape_grammar, double split_parameter, boost::shared_ptr<ShapeSymbol> right_symbol_1,
                 boost::shared_ptr<ShapeSymbol> right_symbol_2);

    inline int position_x()
    {
        return position_x_;
    }
    inline int position_y()
    {
        return position_y_;
    }
    inline int width()
    {
        return width_;
    }
    inline int height()
    {
        return height_;
    }
    inline std::string symbol_name()
    {
        return symbol_name_;
    }
    void set_symbol_name(std::string value);
    inline void set_position_x(int value)
    {
        this->position_x_ = value;
    }
    inline void set_position_y(int value)
    {
        this->position_y_ = value;
    }
    inline void set_width(int value)
    {
        this->width_ = value;
    }
    inline void set_height(int value)
    {
        this->height_ = value;
    }
    inline bool is_terminal()
    {
        return this->is_terminal_;
    }
    inline bool is_atom()
    {
        return this->is_atom_;
    }
    inline void set_is_terminal(bool value)
    {
        this->is_terminal_ = value;
    }
    inline void set_is_atom(bool value)
    {
        this->is_atom_ = value;
    }

private:
    int position_x_, position_y_, width_, height_; /*!< Envelop of this shape symbol. */
    std::string symbol_name_; /*< symbol name. */
    bool is_terminal_, is_atom_; /*< If this symbol is terminal symbol, is atom symbol. */

    boost::shared_ptr<FacadeGrammar> facade_grammar_; /*< The facade grammar that this symbol is in. */
};


#endif // SHAPE_SYMBOL_H
